home *** CD-ROM | disk | FTP | other *** search
- The DES library.
-
- Please note that this library was originally written to operate with
- eBones, a version of Kerberos that had had encryption removed when it left
- the USA and then put back in. As such there are some routines that I will
- advise not using but they are still in the library for historical reasons.
- For all calls that have an 'input' and 'output' variables, they can be the
- same.
-
- This library requires the inclusion of 'des.h'.
-
- All of the encryption functions take what is called a des_key_schedule as an
- argument. A des_key_schedule is an expanded form of the des key.
- A des_key is 8 bytes of odd parity, the type used to hold the key is a
- des_cblock. A des_cblock is an array of 8 bytes, often in this library
- description I will refer to input bytes when the function specifies
- des_cblock's as input or output, this just means that the variable should
- be a multiple of 8 bytes.
-
- The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
- specify decryption. The functions and global variable are as follows:
-
- int des_check_key;
- DES keys are supposed to be odd parity. If this variable is set to
- a non-zero value, des_set_key() will check that the key has odd
- parity and is not one of the known weak DES keys. By default this
- variable is turned off;
-
- void des_set_odd_parity(
- des_cblock *key );
- This function takes a DES key (8 bytes) and sets the parity to odd.
-
- int des_is_weak_key(
- des_cblock *key );
- This function returns a non-zero value if the DES key passed is a
- weak, DES key. If it is a weak key, don't use it, try a different
- one. If you are using 'random' keys, the chances of hitting a weak
- key are 1/2^52 so it is probably not worth checking for them.
-
- int des_set_key(
- des_cblock *key,
- des_key_schedule schedule);
- Des_set_key converts an 8 byte DES key into a des_key_schedule.
- A des_key_schedule is an expanded form of the key which is used to
- perform actual encryption. It can be regenerated from the DES key
- so it only needs to be kept when encryption or decryption is about
- to occur. Don't save or pass around des_key_schedule's since they
- are CPU architecture dependent, DES keys are not. If des_check_key
- is non zero, zero is returned if the key has the wrong parity or
- the key is a weak key, else 1 is returned.
-
- int des_key_sched(
- des_cblock *key,
- des_key_schedule schedule);
- An alternative name for des_set_key().
-
- int des_rw_mode; /* defaults to DES_PCBC_MODE */
- This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
- This specifies the function to use in the enc_read() and enc_write()
- functions.
-
- void des_encrypt(
- unsigned long *data,
- des_key_schedule ks,
- int enc);
- This is the DES encryption function that gets called by just about
- every other DES routine in the library. You should not use this
- function except to implement 'modes' of DES. I say this because the
- functions that call this routine do the conversion from 'char *' to
- long, and this needs to be done to make sure 'non-aligned' memory
- access do not occur. The characters are loaded 'little endian',
- have a look at my source code for more details on how I use this
- function.
- Data is a pointer to 2 unsigned long's and ks is the
- des_key_schedule to use. enc, is non zero specifies encryption,
- zero if decryption.
-
- void des_encrypt2(
- unsigned long *data,
- des_key_schedule ks,
- int enc);
- This functions is the same as des_encrypt() except that the DES
- initial permutation (IP) and final permutation (FP) have been left
- out. As for des_encrypt(), you should not use this function.
- It is used by the routines in my library that implement triple DES.
- IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
- as des_encrypt() des_encrypt() des_encrypt() except faster :-).
-
- void des_ecb_encrypt(
- des_cblock *input,
- des_cblock *output,
- des_key_schedule ks,
- int enc);
- This is the basic Electronic Code Book form of DES, the most basic
- form. Input is encrypted into output using the key represented by
- ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
- decryption occurs. Input is 8 bytes long and output is 8 bytes.
- (the des_cblock structure is 8 chars).
-
- void des_ecb3_encrypt(
- des_cblock *input,
- des_cblock *output,
- des_key_schedule ks1,
- des_key_schedule ks2,
- des_key_schedule ks3,
- int enc);
- This is the 3 key EDE mode of ECB DES. What this means is that
- the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
- then encrypted again with ks3, before being put into output;
- C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt()
- that only takes 2 des_key_schedules that implements,
- C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
-
- void des_cbc_encrypt(
- des_cblock *input,
- des_cblock *output,
- long length,
- des_key_schedule ks,
- des_cblock *ivec,
- int enc);
- This routine implements DES in Cipher Block Chaining mode.
- Input, which should be a multiple of 8 bytes is encrypted
- (or decrypted) to output which will also be a multiple of 8 bytes.
- The number of bytes is in length (and from what I've said above,
- should be a multiple of 8). If length is not a multiple of 8, I'm
- not being held responsible :-). ivec is the initialisation vector.
- This function does not modify this variable. To correctly implement
- cbc mode, you need to do one of 2 things; copy the last 8 bytes of
- cipher text for use as the next ivec in your application,
- or use des_ncbc_encrypt().
- Only this routine has this problem with updating the ivec, all
- other routines that are implementing cbc mode update ivec.
-
- void des_ncbc_encrypt(
- des_cblock *input,
- des_cblock *output,
- long length,
- des_key_schedule sk,
- des_cblock *ivec,
- int enc);
- For historical reasons, des_cbc_encrypt() did not update the
- ivec with the value requires so that subsequent calls to
- des_cbc_encrypt() would 'chain'. This was needed so that the same
- 'length' values would not need to be used when decrypting.
- des_ncbc_encrypt() does the right thing. It is the same as
- des_cbc_encrypt accept that ivec is updates with the correct value
- to pass in subsequent calls to des_ncbc_encrypt(). I advise using
- des_ncbc_encrypt() instead of des_cbc_encrypt();
-
- void des_3cbc_encrypt(
- des_cblock *input,
- des_cblock *output,
- long length,
- des_key_schedule sk1,
- des_key_schedule sk2,
- des_cblock *ivec1,
- des_cblock *ivec2,
- int enc);
- This function is flawed, do not use it. I have left it in the
- library because it is used in my des(1) program and will function
- correctly when used by des(1). If I removed the function, people
- could end up unable to decrypt files.
- This routine implements outer triple cbc encryption using 2 ks and
- 2 ivec's. Use des_ede2_cbc_encrypt() instead.
-
- void des_ede3_cbc_encrypt(
- des_cblock *input,
- des_cblock *output,
- long length,
- des_key_schedule ks1,
- des_key_schedule ks2,
- des_key_schedule ks3,
- des_cblock *ivec,
- int enc);
- This function implements inner triple CBC DES encryption with 3
- keys. What this means is that each 'DES' operation
- inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
- Again, this is cbc mode so an ivec is requires.
- This mode is used by SSL.
- There is also a des_ede2_cbc_encrypt() that only uses 2
- des_key_schedule's, the first being reused for the final
- encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES
- is used by the RSAref library.
-
- void des_pcbc_encrypt(
- des_cblock *input,
- des_cblock *output,
- long length,
- des_key_schedule ks,
- des_cblock *ivec,
- int enc);
- This is Propagating Cipher Block Chaining mode of DES. It is used
- by Kerberos v4. It's parameters are the same as des_ncbc_encrypt().
-
- void des_cfb_encrypt(
- unsigned char *in,
- unsigned char *out,
- int numbits,
- long length,
- des_key_schedule ks,
- des_cblock *ivec,
- int enc);
- Cipher Feedback Back mode of DES. This implementation 'feeds back'
- in numbit blocks. The input (and output) is in multiples of numbits
- bits. numbits needs to be a multiple of 8 bits. Length is the
- number of bytes input.
-
- void des_cfb64_encrypt(
- unsigned char *in,
- unsigned char *out,
- long length,
- des_key_schedule ks,
- des_cblock *ivec,
- int *num,
- int enc);
- This is one of the more useful functions in this DES library, it
- implements CFB mode of DES with 64bit feedback. Why is this
- useful you ask? Because this routine will allow you to encrypt an
- arbitrary number of bytes, no 8 byte padding. Each call to this
- routine will encrypt the input bytes to output and then update ivec
- and num. num contains 'how far' we are though ivec. If this does
- not make much sense, read more about cfb mode of DES :-).
-
- void des_ede3_cfb64_encrypt(
- unsigned char *in,
- unsigned char *out,
- long length,
- des_key_schedule ks1,
- des_key_schedule ks2,
- des_key_schedule ks3,
- des_cblock *ivec,
- int *num,
- int enc);
- Same as des_cfb64_encrypt() accept that the DES operation is
- triple DES. As usual, there is a macro for
- des_ede2_cfb64_encrypt() which reuses ks1.
-
- void des_ofb_encrypt(
- unsigned char *in,
- unsigned char *out,
- int numbits,
- long length,
- des_key_schedule ks,
- des_cblock *ivec);
- This is a implementation of Output Feed Back mode of DES. It is
- the same as des_cfb_encrypt() in that numbits is the size of the
- units dealt with during input and output (in bits).
-
- void des_ofb64_encrypt(
- unsigned char *in,
- unsigned char *out,
- long length,
- des_key_schedule ks,
- des_cblock *ivec,
- int *num);
- The same as des_cfb64_encrypt() except that it is Output Feed Back
- mode.
-
- void des_ede3_ofb64_encrypt(
- unsigned char *in,
- unsigned char *out,
- long length,
- des_key_schedule ks1,
- des_key_schedule ks2,
- des_key_schedule ks3,
- des_cblock *ivec,
- int *num);
- Same as des_ofb64_encrypt() accept that the DES operation is
- triple DES. As usual, there is a macro for
- des_ede2_ofb64_encrypt() which reuses ks1.
-
- int des_read_pw_string(
- char *buf,
- int length,
- char *prompt,
- int verify);
- This routine is used to get a password from the terminal with echo
- turned off. Buf is where the string will end up and length is the
- size of buf. Prompt is a string presented to the 'user' and if
- verify is set, the key is asked for twice and unless the 2 copies
- match, an error is returned. A return code of -1 indicates a
- system error, 1 failure due to use interaction, and 0 is success.
-
- unsigned long des_cbc_cksum(
- des_cblock *input,
- des_cblock *output,
- long length,
- des_key_schedule ks,
- des_cblock *ivec);
- This function produces an 8 byte checksum from input that it puts in
- output and returns the last 4 bytes as a long. The checksum is
- generated via cbc mode of DES in which only the last 8 byes are
- kept. I would recommend not using this function but instead using
- the EVP_Digest routines, or at least using MD5 or SHA. This
- function is used by Kerberos v4 so that is why it stays in the
- library.
-
- char *crypt(
- const char *buf,
- const char *salt);
- This is my fast version of the unix crypt(3) function. This version
- takes only a small amount of space relative to other fast
- crypt() implementations.
-
- void des_string_to_key(
- char *str,
- des_cblock *key);
- This function takes str and converts it into a DES key. I would
- recommend using MD5 instead and use the first 8 bytes of output.
- When I wrote the first version of these routines back in 1990, MD5
- did not exist but I feel these routines are still sound. This
- routines is compatible with the one in MIT's libdes.
-
- void des_string_to_2keys(
- char *str,
- des_cblock *key1,
- des_cblock *key2);
- This function takes str and converts it into 2 DES keys.
- I would recommend using MD5 and using the 16 bytes as the 2 keys.
- I have nothing against these 2 'string_to_key' routines, it's just
- that if you say that your encryption key is generated by using the
- 16 bytes of an MD5 hash, every-one knows how you generated your
- keys.
-
- int des_read_password(
- des_cblock *key,
- char *prompt,
- int verify);
- This routine combines des_read_pw_string() with des_string_to_key().
-
- int des_read_2passwords(
- des_cblock *key1,
- des_cblock *key2,
- char *prompt,
- int verify);
- This routine combines des_read_pw_string() with des_string_to_2key().
-
- void des_random_seed(
- des_cblock key);
- This routine sets a starting point for des_random_key().
-
- void des_random_key(
- des_cblock ret);
- This function return a random key. Make sure to 'seed' the random
- number generator (with des_random_seed()) before using this function.
- I personally now use a MD5 based random number system.
-
- int des_enc_read(
- int fd,
- char *buf,
- int len,
- des_key_schedule ks,
- des_cblock *iv);
- This function will write to a file descriptor the encrypted data
- from buf. This data will be preceded by a 4 byte 'byte count' and
- will be padded out to 8 bytes. The encryption is either CBC of
- PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE,
- pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use
- DES_PCBC_MODE.
-
- int des_enc_write(
- int fd,
- char *buf,
- int len,
- des_key_schedule ks,
- des_cblock *iv);
- This routines read stuff written by des_enc_read() and decrypts it.
- I have used these routines quite a lot but I don't believe they are
- suitable for non-blocking io. If you are after a full
- authentication/encryption over networks, have a look at SSL instead.
-
- unsigned long des_quad_cksum(
- des_cblock *input,
- des_cblock *output,
- long length,
- int out_count,
- des_cblock *seed);
- This is a function from Kerberos v4 that is not anything to do with
- DES but was needed. It is a cksum that is quicker to generate than
- des_cbc_cksum(); I personally would use MD5 routines now.
- =====
- Modes of DES
- Quite a bit of the following information has been taken from
- AS 2805.5.2
- Australian Standard
- Electronic funds transfer - Requirements for interfaces,
- Part 5.2: Modes of operation for an n-bit block cipher algorithm
- Appendix A
-
- There are several different modes in which DES can be used, they are
- as follows.
-
- Electronic Codebook Mode (ECB) (des_ecb_encrypt())
- - 64 bits are enciphered at a time.
- - The order of the blocks can be rearranged without detection.
- - The same plaintext block always produces the same ciphertext block
- (for the same key) making it vulnerable to a 'dictionary attack'.
- - An error will only affect one ciphertext block.
-
- Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
- - a multiple of 64 bits are enciphered at a time.
- - The CBC mode produces the same ciphertext whenever the same
- plaintext is encrypted using the same key and starting variable.
- - The chaining operation makes the ciphertext blocks dependent on the
- current and all preceding plaintext blocks and therefore blocks can not
- be rearranged.
- - The use of different starting variables prevents the same plaintext
- enciphering to the same ciphertext.
- - An error will affect the current and the following ciphertext blocks.
-
- Cipher Feedback Mode (CFB) (des_cfb_encrypt())
- - a number of bits (j) <= 64 are enciphered at a time.
- - The CFB mode produces the same ciphertext whenever the same
- plaintext is encrypted using the same key and starting variable.
- - The chaining operation makes the ciphertext variables dependent on the
- current and all preceding variables and therefore j-bit variables are
- chained together and can not be rearranged.
- - The use of different starting variables prevents the same plaintext
- enciphering to the same ciphertext.
- - The strength of the CFB mode depends on the size of k (maximal if
- j == k). In my implementation this is always the case.
- - Selection of a small value for j will require more cycles through
- the encipherment algorithm per unit of plaintext and thus cause
- greater processing overheads.
- - Only multiples of j bits can be enciphered.
- - An error will affect the current and the following ciphertext variables.
-
- Output Feedback Mode (OFB) (des_ofb_encrypt())
- - a number of bits (j) <= 64 are enciphered at a time.
- - The OFB mode produces the same ciphertext whenever the same
- plaintext enciphered using the same key and starting variable. More
- over, in the OFB mode the same key stream is produced when the same
- key and start variable are used. Consequently, for security reasons
- a specific start variable should be used only once for a given key.
- - The absence of chaining makes the OFB more vulnerable to specific attacks.
- - The use of different start variables values prevents the same
- plaintext enciphering to the same ciphertext, by producing different
- key streams.
- - Selection of a small value for j will require more cycles through
- the encipherment algorithm per unit of plaintext and thus cause
- greater processing overheads.
- - Only multiples of j bits can be enciphered.
- - OFB mode of operation does not extend ciphertext errors in the
- resultant plaintext output. Every bit error in the ciphertext causes
- only one bit to be in error in the deciphered plaintext.
- - OFB mode is not self-synchronising. If the two operation of
- encipherment and decipherment get out of synchronism, the system needs
- to be re-initialised.
- - Each re-initialisation should use a value of the start variable
- different from the start variable values used before with the same
- key. The reason for this is that an identical bit stream would be
- produced each time from the same parameters. This would be
- susceptible to a ' known plaintext' attack.
-
- Triple ECB Mode (des_ecb3_encrypt())
- - Encrypt with key1, decrypt with key2 and encrypt with key3 again.
- - As for ECB encryption but increases the key length to 168 bits.
- There are theoretic attacks that can be used that make the effective
- key length 112 bits, but this attack also requires 2^56 blocks of
- memory, not very likely, even for the NSA.
- - If both keys are the same it is equivalent to encrypting once with
- just one key.
- - If the first and last key are the same, the key length is 112 bits.
- There are attacks that could reduce the key space to 55 bit's but it
- requires 2^56 blocks of memory.
- - If all 3 keys are the same, this is effectively the same as normal
- ecb mode.
-
- Triple CBC Mode (des_ede3_cbc_encrypt())
- - Encrypt with key1, decrypt with key2 and then encrypt with key3.
- - As for CBC encryption but increases the key length to 168 bits with
- the same restrictions as for triple ecb mode.
-